package at.ac.tuwien.prog.memory;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import at.ac.tuwien.prog.entity.Register;

/**
 * 
 * @author christoph.pickl@student.tuwien.ac.at
 */
public class MemoryManagerImpl implements IMemoryManager {

	private static final Log LOG = LogFactory.getLog(MemoryManagerImpl.class);
	
	private final Set<IDisplayDataListener> listeners = new HashSet<IDisplayDataListener>();
	
	private final MemoryData data = new MemoryData();
	
	public Register getRegisterValue(int relativeAddress) {
		return Register.newByInt(this.data.get(relativeAddress));
	}

	public void setRegisterValue(int relativeAddress, Register value) {
		this.data.set(relativeAddress, value.getIntValue());
		
		if(relativeAddress >= MemoryConstants.DISPLAY_DATA_START
		&& relativeAddress <= MemoryConstants.DISPLAY_DATA_END) {
			LOG.debug("notifiying IDisplayDataListeners");
			for (IDisplayDataListener listener : this.listeners) {
				listener.dataChanged(relativeAddress, value);
			}
		}
	}

	public void setProgramCounter(Register address) {
		LOG.debug("setProgramCounter(address="+address+")");
		this.setRegisterValue(MemoryConstants.PROGRAM_COUNTER, address);
	}
	
	
	
	public void addDisplayDataListener(IDisplayDataListener listener) {
		this.listeners.add(listener);
	}

	public boolean removeDisplayDataListener(IDisplayDataListener listener) {
		return this.listeners.remove(listener);
	}

	public Register getProgramCounter() {
		return this.getRegisterValue(MemoryConstants.PROGRAM_COUNTER);
	}

}
